package com.example.mywebrtctest;

import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.Manifest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RendererCommon;
import org.webrtc.RtpReceiver;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
import org.webrtc.audio.AudioDeviceModule;
import org.webrtc.audio.JavaAudioDeviceModule;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class WebrtcActivity extends AppCompatActivity {
    public enum TaskStatus{
        INIT,//初始状态
        GET_INFO,//获取用户信息
        RCV_REQUEST,//收到童话请求
        IN_CALL//通话中
    }
    // 添加权限请求码常量定义
    private static final int PERMISSION_REQUEST_CODE = 100;
    private WebSocketClient socket;


    private final Handler heartBeatHandler = new Handler(Looper.getMainLooper());
    private final Handler mainHandler = new Handler(Looper.getMainLooper());
    private static final long HEART_BEAT_INTERVAL = 5 * 1000; // 心跳间隔30秒
    private boolean isHeartBeating = false;
    // 断线重连相关变量
    private int reconnectAttempts = 0;
    private int heartBeatSentCount = 0;
    private static final int MAX_RECONNECT_ATTEMPTS = 5;
    private static final long RECONNECT_INTERVAL_MS = 3000; // 重连间隔3秒
    private Handler reconnectHandler;//加入房间命令
    private final String cmd_join_room      = "cmd_join_room";
    private final String cmd_ping           = "cmd_ping"; // 心跳命令
    private final String cmd_pong           = "cmd_pong"; // 心跳响应命令
    private final String cmd_new_peer       = "cmd_new_peer";//有新人加入房间
    private final String cmd_offer          = "cmd_offer";
    private final String cmd_answer         = "cmd_answer";
    private final String cmd_ice            = "cmd_ice";
    private final String cmd_av_status      = "cmd_av_status";
    private final String cmd_tel_status     = "cmd_tel_status";
    private final String cmd_login_server   = "cmd_login";
    private final String cmd_current_peers  = "cmd_current_peers";
    private final String cmd_hang_up        = "cmd_hang_up";
    private final String cmd_start_call     = "cmd_start_call";
    private final String cmd_peer_join      = "cmd_peer_join";
    private final String cmd_peer_leave     = "cmd_peer_leave";

    private SurfaceViewRenderer remoteRender;
    private PeerConnection.IceConnectionState iceConnectionState = PeerConnection.IceConnectionState.DISCONNECTED; // 添加ICE连接状态变量
    private SurfaceViewRenderer localRender;
    private TextView ivStatus;
    private View ivJoin;
    private EglBase mRootEGL;

    private String strChannel = "";//渠道
    private String strNode = "";//节点
    private String strNumber = "";//订单号
    private String strName = "";//名字
    private String strCount = "";//金额
    //接听按钮
    private ImageButton btnAnswer;
    //免提按钮
    private ImageButton btnSpeaker;
    //静音按钮
    private ImageButton btnMute;
    //头像重置
    private ImageButton btnHead;
    //挂断按钮
    private ImageButton btnHangup;
    //客户渠道
    private TextView txtChannel;
    //客户节点
    private TextView txtNode;
    //客户信息背景
    private ImageView bgInfo;
    //客户信息符号
    private TextView txtSymbol;
    //客户信息
    private TextView txtInfo;
    //订单号
    private TextView txtNumber;
    //姓名
    private TextView txtName;
    //融资额
    private TextView txtCount;
    //无信息提示
    private TextView txtTips;

    private PeerConnectionFactory factory;
    private VideoCapturer videoCapturer;
    private AudioSource audioSource;
    private AudioTrack localAudioTrack;
    private VideoSource videoSource;
    private VideoTrack videoTrack;
    
    private AudioManager audioManager;
    private boolean isUseMicPhone = true;//是否启用麦克风
    private boolean isSpeakerOn   = true;//是否使用扬声器
    private final List<PeerConnection.IceServer> iceServers = new ArrayList<>();

    private SurfaceTextureHelper surfaceTextureHelper;
    private PeerConnection peerConnection;
    private String remoteUid;

    private String roomId    = "300";//房间号
    private final String uid = "1122314";//UUID.randomUUID().toString();
    private final String tag = "chen";
    //测试服
    //private final String XLurl   = "wss://47.101.40.207:8299";  //信令服务器
    //private final String Turnurl = "turn:47.101.40.207:3478";   //turn服务器
    //private final String Stunurl = "stun:47.101.40.207:3478";   //sturn服务器
    // 正式服
    private final String XLurl   = "wss://polaris.uat.yixincapital.com/aio-webrtc/";  //信令服务器
    private final String Turnurl = "turn:123.103.73.215:3478";   //turn服务器
    private final String Stunurl = "stun:123.103.73.215:3478";   //sturn服务器

    //用户名
    private final String turnUserName = "turn";
    //密码
    private final String turnPassWord = "turntest";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webrtc);
        ivStatus = findViewById(R.id.ivStatus);
        ivJoin = findViewById(R.id.ivJoin);
        remoteRender = findViewById(R.id.ivRemoteRender);
        localRender = findViewById(R.id.ivLocalRender);
        txtChannel = findViewById(R.id.textView1);
        txtNode = findViewById(R.id.textView2);
        txtInfo = findViewById(R.id.textView4);
        txtSymbol = findViewById(R.id.textView3);
        bgInfo = findViewById(R.id.imageView7);
        txtNumber = findViewById(R.id.textView6);
        txtName =findViewById(R.id.textView7);
        txtCount =findViewById(R.id.textView8);
        txtTips = findViewById(R.id.textView9);
        btnAnswer = findViewById(R.id.btn_answer);
        btnSpeaker =findViewById(R.id.imageButton2);
        btnMute = findViewById(R.id.imageButton4);
        btnHangup = findViewById(R.id.imageButton3);
        btnHead = findViewById(R.id.head_frame);
        //初始化重连Handler
        reconnectHandler = new Handler(Looper.getMainLooper());
        //进入app首页隐藏以下组件
        changeState(TaskStatus.INIT);

        // 检查并请求权限
        if (!checkPermissions()) {
            requestPermissions();
        } else {
            createSocket();
            initWebRTC();
        }
        //绑定点击事件
        bindClickListener();

        // 设置屏幕常亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    private void changeState(TaskStatus status){
        // 判空检查：避免Activity销毁后操作UI
        if (isDestroyed() || isFinishing()) {
            return;
        }

        switch (status){
            case GET_INFO:
                localRender.setVisibility(View.INVISIBLE);
                remoteRender.setVisibility(View.INVISIBLE);
                btnHangup.setVisibility(View.INVISIBLE);
                btnMute.setVisibility(View.INVISIBLE);
                btnSpeaker.setVisibility(View.INVISIBLE);
                btnAnswer.setVisibility(View.VISIBLE);
                txtTips.setVisibility(View.INVISIBLE);
                txtNumber.setVisibility(View.VISIBLE);
                txtName.setVisibility(View.VISIBLE);
                txtCount.setVisibility(View.VISIBLE);
                txtSymbol.setVisibility(View.VISIBLE);
                txtInfo.setVisibility(View.VISIBLE);
                bgInfo.setVisibility(View.VISIBLE);
                break;
            case IN_CALL:
                localRender.setVisibility(View.INVISIBLE);
                remoteRender.setVisibility(View.VISIBLE);
                btnHangup.setVisibility(View.VISIBLE);
                btnMute.setVisibility(View.VISIBLE);
                btnSpeaker.setVisibility(View.VISIBLE);
                btnAnswer.setVisibility(View.INVISIBLE);
                txtTips.setVisibility(View.INVISIBLE);
                txtNumber.setVisibility(View.INVISIBLE);
                txtName.setVisibility(View.INVISIBLE);
                txtCount.setVisibility(View.INVISIBLE);
                txtSymbol.setVisibility(View.INVISIBLE);
                txtInfo.setVisibility(View.INVISIBLE);
                bgInfo.setVisibility(View.INVISIBLE);
                break;
            case INIT:
                localRender.setVisibility(View.INVISIBLE);
                remoteRender.setVisibility(View.INVISIBLE);
                btnHangup.setVisibility(View.INVISIBLE);
                btnMute.setVisibility(View.INVISIBLE);
                btnSpeaker.setVisibility(View.INVISIBLE);
                btnAnswer.setVisibility(View.INVISIBLE);
                txtTips.setVisibility(View.VISIBLE);
                txtNumber.setVisibility(View.INVISIBLE);
                txtName.setVisibility(View.INVISIBLE);
                txtCount.setVisibility(View.INVISIBLE);
                txtSymbol.setVisibility(View.VISIBLE);
                txtInfo.setVisibility(View.VISIBLE);
                bgInfo.setVisibility(View.VISIBLE);
                break;
            case RCV_REQUEST:
                localRender.setVisibility(View.INVISIBLE);
                remoteRender.setVisibility(View.INVISIBLE);
                btnHangup.setVisibility(View.INVISIBLE);
                btnMute.setVisibility(View.INVISIBLE);
                btnSpeaker.setVisibility(View.INVISIBLE);
                btnAnswer.setVisibility(View.VISIBLE);
                txtTips.setVisibility(View.INVISIBLE);
                txtNumber.setVisibility(View.VISIBLE);
                txtName.setVisibility(View.VISIBLE);
                txtCount.setVisibility(View.VISIBLE);
                txtSymbol.setVisibility(View.VISIBLE);
                txtInfo.setVisibility(View.VISIBLE);
                bgInfo.setVisibility(View.VISIBLE);
                break;
            default:
                break;
        }
    }
    private boolean checkPermissions() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermissions() {
        ActivityCompat.requestPermissions(this,
            new String[]{
                Manifest.permission.CAMERA,
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.MODIFY_AUDIO_SETTINGS
            },
            PERMISSION_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }

            if (allGranted) {
                initWebRTC();
            } else {
                // 处理权限被拒绝的情况
                Toast.makeText(this, "需要相机和麦克风权限才能使用视频通话功能", Toast.LENGTH_LONG).show();
                // 可以选择退出应用或禁用相关功能
            }
        }
    }

    // 替换原有的音频约束设置
    private void optimizeAudioSettings() {
        if (factory == null) {
            Log.e(tag, "optimizeAudioSettings: PeerConnectionFactory 为null，无法创建音频源");
            return;
        }

        // 使用更全面的音频约束
        MediaConstraints audioConstraints = new MediaConstraints();
        
        // 音频回声消除和噪音抑制设置
        // 使用optional而不是mandatory，以提高兼容性
        /*
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googEchoCancellation", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googEchoCancellation2", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googEchoCancellation3", "true")); // 启用第三代回声消除
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAutoGainControl", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAutoGainControl2", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googNoiseSuppression", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googNoiseSuppression2", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googNoiseSuppression3", "true")); // 启用第三代噪音抑制
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googHighpassFilter", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googTypingNoiseDetection", "true"));
        */

        // 降低约束要求，提高跨平台兼容性
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googEchoCancellation", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googNoiseSuppression", "true"));
        audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAutoGainControl", "true"));

        // 设置音频通道数为单声道
        // audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAudioChannels", "1"));
        
        // 添加带宽和网络适应性设置
        // audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAudioNetworkAdaptor", "true"));
        
        // 创建新的音频源
        if (audioSource != null) {
            audioSource.dispose();
        }
        audioSource = factory.createAudioSource(audioConstraints);
        
        // 重新创建音频轨道
        if (localAudioTrack != null) {
            localAudioTrack.dispose();
        }
        localAudioTrack = factory.createAudioTrack("102", audioSource);
        localAudioTrack.setEnabled(true);
        Log.d(tag, "音频轨道已启用: " + localAudioTrack.enabled());

        // 注意：WebRTC版本不支持setContentHint方法，已移除
        // 音频优化通过其他配置参数实现
    }

    private void initWebRTC() {
        //在初次使用PeerConnectionFactory之前，必须调用静态方法 initialize() 对其进行全局的初始化与资源加载
        PeerConnectionFactory.InitializationOptions initializationOptions =
                PeerConnectionFactory.InitializationOptions
                        .builder(this)
                        .setEnableInternalTracer(true)// 启用内部追踪器，用来记录一些相关数据
                        .createInitializationOptions();

        PeerConnectionFactory.initialize(initializationOptions);

        iceServers.clear();
        iceServers.add(
                PeerConnection.IceServer.builder(Turnurl)
                        .setUsername(turnUserName)
                        .setPassword(turnPassWord)
                        .createIceServer());
        iceServers.add(PeerConnection.IceServer.builder(Stunurl).createIceServer());
    }

    // 初始化webrtc
    private void createWebrtc(){
         destroyWebrtc();

        Log.e(tag,"cmd 正在初始化WebRTC");

        // 初始化音频管理器
        if (audioManager == null) {
            audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        }
        // 设置音频模式为通信模式以优化通话质量
        audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);

        setSpeakerOn(true);

        if (mRootEGL == null) {
            mRootEGL = EglBase.create();
        }

        Log.e(tag,"cmd 正在创建PeerConnectionFactory");
        //-----------创建视频编码和解码器
        VideoEncoderFactory encoderFactory = new DefaultVideoEncoderFactory(mRootEGL.getEglBaseContext(),
                true, true);
        VideoDecoderFactory decoderFactory = new DefaultVideoDecoderFactory(mRootEGL.getEglBaseContext());


        //-----------创建 PeerConnectionFactory
        // 创建 AudioDeviceModule，并尝试启用硬件回声消除和噪音抑制
        JavaAudioDeviceModule.Builder admBuilder = JavaAudioDeviceModule.builder(this);
        admBuilder.setUseHardwareAcousticEchoCanceler(true);
        admBuilder.setUseHardwareNoiseSuppressor(true);
        Log.d(tag, "尝试启用硬件回声消除和噪音抑制");
        
        // 设置单声道输入输出
        admBuilder.setUseStereoInput(false);
        admBuilder.setUseStereoOutput(false);
        
        // 在当前WebRTC版本中，音频缓冲区大小、采样深度和采样率等参数由系统自动管理
        // 系统会根据设备硬件能力和网络条件自动选择最佳配置
        
        // 创建AudioDeviceModule
        AudioDeviceModule adm = admBuilder.createAudioDeviceModule();
        // 确保音频焦点
        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
        if (factory == null) {
            factory = PeerConnectionFactory.builder()
                .setOptions(options)//设置网络配置,使用默认
                .setAudioDeviceModule(adm)//设置音频采集和播放使用的配置,当前使用java中的audioTrack 和audioRecord
                .setVideoEncoderFactory(encoderFactory)
                .setVideoDecoderFactory(decoderFactory)
                .createPeerConnectionFactory();
        }
        if (factory == null) { // 原逻辑为 factory != null，此处反转
            try {
                factory = PeerConnectionFactory.builder()
                        .setOptions(options)
                        .setAudioDeviceModule(adm)
                        .setVideoEncoderFactory(encoderFactory)
                        .setVideoDecoderFactory(decoderFactory)
                        .createPeerConnectionFactory();
                Log.e(tag, "PeerConnectionFactory 创建成功");
            } catch (Exception e) {
                Log.e(tag, "PeerConnectionFactory 创建失败：" + e.getMessage(), e);
                // 初始化失败时提示用户，避免后续崩溃
                runOnUiThread(() -> Toast.makeText(WebrtcActivity.this,
                        "WebRTC初始化失败，请重试", Toast.LENGTH_SHORT).show());
                return; // 终止后续流程，防止空指针
            }
        }
        if (factory == null) {
            Log.e(tag, "webrtc初始化失败");
            return;
        }

        Log.e(tag,"cmd 正在创建声音源");
        // 创建声源
        optimizeAudioSettings();
        // 默认不静音
        setMicrophoneOn(true);

        //----------创建视频源
        //ScreenCapturerAndroid 录屏 ；FileVideoCapturer文件
        //从相机里获取视频流
        CameraEnumerator enumerator = new Camera2Enumerator(this);
        String[] deviceNames = enumerator.getDeviceNames();
        //遍历所有摄像头找到前置摄像头
        for (String deviceName : deviceNames) {
            if (enumerator.isFrontFacing(deviceName)) {
                videoCapturer = enumerator.createCapturer(deviceName, null);
            }
        }

        if (videoCapturer == null) {
            Log.e(tag, "未找到可用摄像头");
            runOnUiThread(() -> Toast.makeText(WebrtcActivity.this,
                    "未找到可用摄像头", Toast.LENGTH_SHORT).show());
            return;
        }

        videoSource = factory.createVideoSource(videoCapturer.isScreencast());
        //创建视频轨道
        videoTrack = factory.createVideoTrack("103", videoSource);

        //因为使用的是opengl 渲染
        surfaceTextureHelper = SurfaceTextureHelper.create("capture-thread", mRootEGL.getEglBaseContext());
        videoCapturer.initialize(surfaceTextureHelper, this, videoSource.getCapturerObserver());
        //开始录制
        videoCapturer.startCapture(
                720,//宽
                1080,//高
                25//fps 帧率
        );
        Log.e(tag,"cmd 正在本地预览");

        //播放本地视频
        localRender.init(mRootEGL.getEglBaseContext(), null);
        //SCALE_ASPECT_FILL 自动适应屏幕比例， 画面存在被裁剪的可能
        //SCALE_ASPECT_FIT 自动适应画面比例，屏幕上可能存在黑边
        //SCALE_ASPECT_BALANCED  视频尺寸非等比缩放。保证视频内容全部显示，且填满视窗。
        localRender.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
        localRender.setMirror(true);//启用镜像
        //localRender.setScaleX(-1);
        videoTrack.addSink(localRender);//最后播放

        //初始化远端render ，因为使用opengl渲染所以 必须在在主线程初始化
        remoteRender.init(mRootEGL.getEglBaseContext(), null);
        remoteRender.setMirror(true);//启用镜像
        //localRender.setScaleX(-1);
        remoteRender.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);

        //创建peerConnection
        Log.e(tag,"cmd 正在创建 peerConnection");
        peerConnection = factory.createPeerConnection(iceServers, new PeerConnection.Observer() {
            @Override
            public void onSignalingChange(PeerConnection.SignalingState signalingState) {

            }

            @Override
            public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
                //ICE 连接状态变化后回调
                Log.e(tag, "ICE连接状态变化: " + iceConnectionState.name());
                WebrtcActivity.this.iceConnectionState = iceConnectionState;
            }

            @Override
            public void onIceConnectionReceivingChange(boolean b) {

            }

            @Override
            public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {

            }

            @Override
            public void onIceCandidate(IceCandidate iceCandidate) {
                //自动请求stun/turn服务器后回调这个方法
                //发送Ice信息给对端用户
                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_ice);
                    sendObj.put("uid", uid);
                    sendObj.put("remoteUid", remoteUid);
                    sendObj.put("roomId",roomId);
                    JSONObject msgObj = new JSONObject();
                    msgObj.put("sdpMid", iceCandidate.sdpMid);
                    msgObj.put("sdpMLineIndex", iceCandidate.sdpMLineIndex);
                    msgObj.put("sdp", iceCandidate.sdp);
                    sendObj.put("msg", msgObj);
                    socket.send(sendObj.toString());

                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {

            }

            @Override
            public void onAddStream(MediaStream mediaStream) {
                try {
                    // 检查mediaStream是否为空
                    if (mediaStream == null) {
                        Log.e(tag, "Received null media stream");
                        return;
                    }

                    // 处理视频轨道
                    if (mediaStream.videoTracks != null && !mediaStream.videoTracks.isEmpty()) {
                        VideoTrack videoTrack = mediaStream.videoTracks.get(0);
                        if (videoTrack != null && remoteRender != null) {
                            videoTrack.addSink(remoteRender);
                            
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                   changeState(TaskStatus.IN_CALL);
                                }
                            });
                        } else {
                            Log.w(tag, "Video track or remote render is null");
                        }
                    } else {
                        Log.w(tag, "No video tracks in media stream");
                    }

                    // 处理音频轨道
                    if (mediaStream.audioTracks != null && !mediaStream.audioTracks.isEmpty()) {
                        AudioTrack audioTrack = mediaStream.audioTracks.get(0);
                        if (audioTrack != null) {
                            audioTrack.setEnabled(true);
                            // 如果需要设置音频输出设备（如听筒或扬声器）
                            // 需要额外代码配置音频管理器
                        } else {
                            Log.w(tag, "Audio track is null");
                        }
                    } else {
                        Log.w(tag, "No audio tracks in media stream");
                    }
                } catch (Exception e) {
                    Log.e(tag, "Error processing media stream: " + e.getMessage());
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void onRemoveStream(MediaStream mediaStream) {
                Log.e(tag, "cmd 检测到流断开 " );
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // 更新UI的代码
                        changeState(TaskStatus.INIT);
                    }
                });
            }

            @Override
            public void onDataChannel(DataChannel dataChannel) {

            }

            @Override
            public void onRenegotiationNeeded() {

            }

            @Override
            public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {

            }
        });

        List<String> streamIds = Collections.singletonList("local_stream");
        if (peerConnection != null) {
            if (localAudioTrack != null) {
                Log.d(tag, "添加本地音频轨道到PeerConnection，状态: " + localAudioTrack.enabled());
                peerConnection.addTrack(localAudioTrack, streamIds);
            } else {
                Log.e(tag, "本地音频轨道为空，无法添加到PeerConnection");
            }
        } else {
            Log.e(tag,"peerConnection 创建失败");
        }
    }
    private void destroyWebrtc() {
        Log.e(tag, "开始销毁WebRTC资源");

        if (isDestroyed()) { // 避免Activity销毁后继续操作
            Log.e(tag, "Activity已销毁，跳过资源释放");
            return;
        }

        if(peerConnection != null){
            peerConnection.close();
            peerConnection.dispose();
            peerConnection = null;
            Log.e(tag, "PeerConnection 已销毁");
        }
        if (localAudioTrack != null) {
            localAudioTrack.setEnabled(false); // 先禁用轨道
            localAudioTrack.dispose();
            localAudioTrack = null;
            Log.e(tag, "本地音频轨道已销毁");
        }
        if (videoTrack != null) {
            videoTrack.setEnabled(false); // 先禁用轨道
            videoTrack.dispose(); // 释放视频轨道
            videoTrack = null;
            Log.e(tag, "本地视频轨道已销毁");
        }
        // 停止并释放 VideoCapturer（相机资源必须在轨道后释放）
        if (videoCapturer != null) {
            try {
                videoCapturer.stopCapture(); // 停止相机采集（必须调用，否则相机服务被占用）
                videoCapturer.dispose(); // 释放相机设备
                videoCapturer = null;
                Log.e(tag, "VideoCapturer 已销毁");
            } catch (InterruptedException e) {
                Log.e(tag, "停止相机采集失败：" + e.getMessage());

            }
        }
        if(surfaceTextureHelper != null){
            surfaceTextureHelper.dispose();
            surfaceTextureHelper = null;
            Log.e(tag, "SurfaceTextureHelper 已销毁");
        }

        if (mRootEGL != null) {
            mRootEGL.release(); // 释放EGL上下文
            mRootEGL = null;
            Log.e(tag, "EGL上下文已销毁");
        }

        if (videoSource != null) {
            videoSource.dispose();
            videoSource = null;
            Log.e(tag, "VideoSource 已销毁");
        }
        if (audioSource != null) {
            audioSource.dispose();
            audioSource = null;
            Log.e(tag, "AudioSource 已销毁");
        }

        if (factory != null) {
            factory.dispose();
            factory = null;
            Log.e(tag, "PeerConnectionFactory 已销毁");
        }
        if(mRootEGL != null){
            mRootEGL.release();
            mRootEGL = null;
        }


        // 释放渲染器（必须在EGL后释放，避免OpenGL资源冲突）
//        mainHandler.post(() -> { // 确保在主线程释放UI渲染资源
//            if (localRender != null) {
//                localRender.release();
//                // localRender = null;
//            }
//            if (remoteRender != null) {
//                remoteRender.release();
//                // remoteRender = null;
//            }
//            Log.e(tag, "渲染器已销毁");
//
//            Log.e(tag, "webrtc销毁完成");
//
//        });

        if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
            if (localRender != null) {
                localRender.release();
            }
            if (remoteRender != null) {
                remoteRender.release();
            }
            Log.e(tag, "渲染器已销毁");

            Log.e(tag, "=========== webrtc销毁完成 =========== ");
        }
    }

    private void bindClickListener(){
        ivJoin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!socket.isOpen()) {
                    return;
                }
                ivStatus.setText("正在加入房间...");
                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_join_room);
                    sendObj.put("uid", uid);
                    sendObj.put("roomId", roomId);
                    socket.send(sendObj.toString());
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });
        //接听
        btnAnswer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!socket.isOpen()) {
                    return;
                }
                // ivStatus.setText("正在加入房间...");
                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_join_room);
                    sendObj.put("uid", uid);
                    sendObj.put("roomId", roomId);
                    socket.send(sendObj.toString());
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }

            }
        });

        //静音
        btnMute.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //关闭麦克风
                setMicrophoneOn(!isUseMicPhone);

                if (!socket.isOpen()) {
                    return;
                }
                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_av_status);
                    sendObj.put("uid", uid);
                    sendObj.put("roomId", roomId);

                    JSONObject msgObj = new JSONObject();
                    msgObj.put("is_share", false);
                    msgObj.put("mic", isUseMicPhone);
                    msgObj.put("cam", isSpeakerOn);
                    msgObj.put("mirror", false);

                    sendObj.put("msg", msgObj);

                    socket.send(sendObj.toString());
                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //挂断
        btnHangup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!socket.isOpen()) {
                    return;
                }
                //结束通话
                doHangUp();
                changeState(TaskStatus.INIT);

                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_hang_up);
                    sendObj.put("uid", uid);
                    sendObj.put("roomId", roomId);
                    socket.send(sendObj.toString());

                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //扬声器
        btnSpeaker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setSpeakerOn(!isSpeakerOn);

                JSONObject sendObj = new JSONObject();
                try {
                    sendObj.put("cmd", cmd_av_status);
                    sendObj.put("uid", uid);
                    sendObj.put("roomId", roomId);

                    JSONObject msgObj = new JSONObject();
                    msgObj.put("is_share", false);
                    msgObj.put("mic", isUseMicPhone);
                    msgObj.put("cam", isSpeakerOn);
                    msgObj.put("mirror", false);
                    sendObj.put("msg", msgObj);
                    socket.send(sendObj.toString());

                } catch (JSONException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    private void setSpeakerOn(boolean isSpkOn) {
        isSpeakerOn = isSpkOn;
        if (audioManager != null) {
            audioManager.setSpeakerphoneOn(isSpeakerOn);
        }
        // 更新按钮图标
        if (isSpeakerOn) {
            btnSpeaker.setImageResource(R.drawable.btn_cancel_mianti); // 扬声器开启图标
            btnSpeaker.setContentDescription("耳机");
        } else {
            btnSpeaker.setImageResource(R.drawable.btn_mianti); // 扬声器关闭图标
            btnSpeaker.setContentDescription("听筒");
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isSpeakerOn) {
                    Toast.makeText(WebrtcActivity.this, "扬声器已开启", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(WebrtcActivity.this, "听筒模式", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    private void setMicrophoneOn(boolean isMicOn) {
        isUseMicPhone = isMicOn;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(isMicOn){
                    btnMute.setImageResource(R.drawable.btn_jingyin);
                    Toast.makeText(WebrtcActivity.this, "麦克风已开启", Toast.LENGTH_SHORT).show();
                }else{
                    btnMute.setImageResource(R.drawable.btn_cancel_jingyin);
                    Toast.makeText(WebrtcActivity.this, "麦克风已静音", Toast.LENGTH_SHORT).show();
                }
            }
        });

        if (localAudioTrack != null) {
            localAudioTrack.setEnabled(isMicOn);
        }
    }

    private void createSocket() {
        // 标记正在创建连接
        closeSocket();

        URI uri = null;//信令服务器地址
        try {
            String newUrl = XLurl + "?roomId=" + roomId + "&uid=" + uid;
            Log.e(tag, "创建新的 socket 连接: " + newUrl);
            uri = new URI(newUrl);
        } catch (Exception e) {
            Log.e(tag, " socket 创建失败: " + e.getMessage());
            return;
        }

        try {
            socket = new WebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    if (isDestroyed()) {
                        return;
                    }

                    Log.e(tag, "链接socket成功");
                    // 连接成功，重置重连计数器
                    reconnectAttempts = 0;
                    heartBeatSentCount = 0;

                    // 登录服务器
                    loginServer();
                    // 登录成功后启动心跳
                    startHeartBeat();

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WebrtcActivity.this, "信令服务器连接成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onMessage(String message) {
                    if (isDestroyed()) {
                        return;
                    }
                    try {
                        JSONObject msgObj = new JSONObject(message);
                        String cmd = msgObj.getString("cmd");
                        Log.e(tag, "收到消息:" + message);
                        // 使用mainHandler将所有命令处理切换到主线程
                        mainHandler.post(() -> {
                            switch (cmd) {
                                case cmd_new_peer: //有新人加入房间
                                    handleNewPeer(msgObj);
                                    break;
                                case cmd_offer: //收到offer请求
                                    handleOffer(msgObj);
                                    break;
                                case cmd_answer: //收到answer请求
                                    handleAnswer(msgObj);
                                    break;
                                case cmd_ice:   //收到ice信息
                                    handleIce(msgObj);
                                    break;
                                case cmd_av_status: //收到共享屏幕相关
                                    handleAVStatus(msgObj);
                                    break;
                                case cmd_tel_status: //收到通话邀请
                                    changeState(TaskStatus.RCV_REQUEST);
                                    break;
                                case cmd_current_peers:
                                    handleLoginSuccess(msgObj);
                                    break;
                                case cmd_start_call:
                                    handleGetUserInfo(msgObj);
                                    break;
                                case cmd_peer_join:
                                    handleGetNodeInfo(msgObj);
                                    break;
                                case cmd_hang_up:
                                    handleHangUp(msgObj);
                                    break;
                                case cmd_peer_leave:
                                    // handlePeerLeave(msgObj);
                                    break;
                                case cmd_pong:  // 处理心跳响应
                                    heartBeatSentCount = 0;
                                    break;
                                default:
                                    Log.d(tag, "收到未知指令: " + cmd);
                                    break;
                            }
                        });
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    if (isDestroyed()) {
                        return;
                    }

                    Log.e(tag, "WebSocket关闭: code=" + code + ", reason=" + reason + ", remote=" + remote);
                    
                    // 停止心跳
                    stopHeartBeat();

                    // 只有在以下情况才尝试重连：
                    // 不是正常关闭（code != 1000 表示异常关闭）或关闭是由服务器发起的（remote为true）
                    if (code != 1000 || remote) {
                        // 显示断线提示
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(WebrtcActivity.this, "连接已断开，尝试重连...", Toast.LENGTH_SHORT).show();
                                // 如果当前是通话状态，切换回初始状态
                                if (peerConnection != null && iceConnectionState == PeerConnection.IceConnectionState.CONNECTED) {
                                    doHangUp();
                                    changeState(TaskStatus.INIT);
                                }
                            }
                        });

                        // 开始重连
                        attemptReconnect();
                    }
                }

                @Override
                public void onError(Exception ex) {
                    if (isDestroyed()) {
                        return;
                    }
                    Log.e(tag, "socket错误: " + ex.toString());

                    // 网络错误时也尝试重连
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(WebrtcActivity.this, "网络连接错误，尝试重连...", Toast.LENGTH_SHORT).show();
                        }
                    });
                    attemptReconnect();

                }
            };
            socket.connect();
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }

    }
    private void closeSocket() {
        stopHeartBeat();

        if (socket != null) {
            try {
                socket.close();
                Log.e(tag, "socket连接已关闭");
            } catch (Exception e) {
                Log.e(tag, "关闭旧socket时出错: " + e.getMessage());
            }
            socket = null;
        }
    }

    /**
     * 启动心跳
     */
    private void startHeartBeat() {
        stopHeartBeat();

        isHeartBeating = true;
        Log.d(tag, "开始发送心跳，间隔: " + HEART_BEAT_INTERVAL + "ms");

        // 立即发送一次心跳，然后每隔指定时间发送一次
        sendHeartBeat();
        heartBeatHandler.postDelayed(heartBeatTask, HEART_BEAT_INTERVAL);
    }

    /**
     * 停止心跳
     */
    private void stopHeartBeat() {
        if (isHeartBeating) {
            heartBeatHandler.removeCallbacks(heartBeatTask);
            isHeartBeating = false;
            Log.d(tag, "停止发送心跳");
        }
    }

    /**
     * 心跳任务
     */
    private final Runnable heartBeatTask = new Runnable() {
        @Override
        public void run() {
            // 发送的心跳没有收到响应, 次数超过3次则断开重连
            if (heartBeatSentCount >= 3) {
                Log.e(tag, "心跳超时3次后, 确定网络已断开, 开始尝试重新连接");
                attemptReconnect();
                return;
            }

            sendHeartBeat();
            heartBeatHandler.postDelayed(this, HEART_BEAT_INTERVAL);
        }
    };

    /**
     * 发送心跳消息
     */
    private void sendHeartBeat() {
        try {
            heartBeatSentCount++;
            if (socket != null) {
                JSONObject pingObj = new JSONObject();
                pingObj.put("cmd", cmd_ping);
                pingObj.put("uid", uid);
                pingObj.put("roomId", roomId);
                pingObj.put("timestamp", System.currentTimeMillis());

                socket.send(pingObj.toString());
                Log.d(tag, "发送心跳消息: " + pingObj.toString());
            }

        } catch (JSONException e) {
            Log.e(tag, "发送心跳失败: " + e.getMessage());
        }
    }


    private void loginServer(){
        if (!socket.isOpen()) {
            return;
        }
        JSONObject sendObj = new JSONObject();
        try {
            sendObj.put("cmd", cmd_login_server);
            sendObj.put("uid", uid);
            sendObj.put("roomId", roomId);
            socket.send(sendObj.toString());
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

    }
    private void handleHangUp(JSONObject msgObj){
        mainHandler.post(() -> {
            if (isDestroyed()) {
                Log.e(tag, "Activity已销毁，跳过handleHangUp");
                return;
            }
            doHangUp();
            Log.e(tag, "已处理挂断命令");
        });
    }

    private void handleLoginSuccess(JSONObject msgObj){
        try{
            JSONObject mObj = msgObj.getJSONObject("msg");
            strChannel = "当前客户渠道：" + mObj.getString("cus_channel");
            strNode = "当前客户节点：" + mObj.getString("cus_node");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 更新UI的代码
                    txtChannel.setText(strChannel);
                    txtNode.setText(strNode);
                }
            });

        } catch (JSONException e) {
            Log.e(tag,"读取客户信息失败:" + e.getMessage());
            throw new RuntimeException(e);
        }
    }
    
    private void handleGetNodeInfo(JSONObject msgObj){
        try{
            JSONObject mObj = msgObj.getJSONObject("msg");
            strChannel = "当前客户渠道：" + mObj.getString("cus_channel");
            strNode = "当前客户节点：" + mObj.getString("cus_node");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 更新UI的代码
                    txtChannel.setText(strChannel);
                    txtNode.setText(strNode);
                }
            });

        } catch (JSONException e) {
            Log.e(tag,"读取渠道信息失败:" + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    private void handleGetUserInfo(JSONObject msgObj){
        try{
            JSONObject mObj = msgObj.getJSONObject("msg");
            strNumber = "订单号：" + mObj.getString("order_id");
            strName = "姓    名：" + mObj.getString("name");
            strCount = "融资金额：" + mObj.getString("amount");
            roomId = msgObj.getString("roomId");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 更新UI的代码
                    changeState(TaskStatus.RCV_REQUEST);
                    txtNumber.setText(strNumber);
                    txtName.setText(strName);
                    txtCount.setText(strCount);
                }
            });
        } catch (JSONException e) {
            Log.e(tag,"读取客户信息失败:" + e.getMessage());
            throw new RuntimeException(e);
        }
    }
    private void handleAVStatus(JSONObject msgObj) {
        //收到对方的ice信息
        try {
            Log.e(tag,"设置镜像翻转");
            JSONObject iceObj = msgObj.getJSONObject("msg");
            remoteRender.setMirror( !iceObj.getBoolean("is_share"));


        } catch (JSONException e) {
            Log.e(tag,"镜像设置失败:" + e.getMessage());
            throw new RuntimeException(e);
        }

    }
    private void handleIce(JSONObject msgObj) {
        //收到对方的ice信息
        try {
            Log.e(tag,"设置ICE信息");
            JSONObject iceObj = msgObj.getJSONObject("msg");
            IceCandidate iceCandidate = new IceCandidate(iceObj.getString("sdpMid"),
                    iceObj.getInt("sdpMLineIndex"),
                    iceObj.getString("sdp"));

            peerConnection.addIceCandidate(iceCandidate);


        } catch (JSONException e) {
            Log.e(tag,"ice设置失败:" + e.getMessage());
            throw new RuntimeException(e);
        }

    }

    private void handleAnswer(JSONObject msgObj) {
        //收到answer,当前是发起通话者
        try {
            String sdpDescription = msgObj.getString("msg");
            SessionDescription sdp = new SessionDescription(SessionDescription.Type.ANSWER, sdpDescription);
            peerConnection.setRemoteDescription(new SdpObserver() {
                @Override
                public void onCreateSuccess(SessionDescription sessionDescription) {

                }

                @Override
                public void onSetSuccess() {
                    // setRemoteDescription 设置成功

                }

                @Override
                public void onCreateFailure(String s) {

                }

                @Override
                public void onSetFailure(String s) {

                }
            }, sdp);

        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

    }

    private void handleOffer(JSONObject msgObj) {
        //收到offer, 当前身份是被呼叫者
        try {
            //发起通话者的uid
            remoteUid = msgObj.getString("uid");
            String sdpDescription = msgObj.getString("msg");
            SessionDescription sdp = new SessionDescription(SessionDescription.Type.OFFER, sdpDescription);
            peerConnection.setRemoteDescription(new SdpObserver() {
                private boolean isCreateAnswer;
                private String sdpDescription;

                @Override
                public void onCreateSuccess(SessionDescription sessionDescription) {
                    //createAnswer 创建成功时候回调
                    Log.e(tag,"创建answer成功");
                    sdpDescription = sessionDescription.description;
                    peerConnection.setLocalDescription(this, sessionDescription);
                }

                @Override
                public void onSetSuccess() {
                    //setRemoteDescription setLocalDescription 成功时候的回调
                    if (!isCreateAnswer) {
                        Log.e(tag,"onSetSuccess1");
                        //还未创建answer 说明是setRemoteDescription回调
                        isCreateAnswer = true;
                        MediaConstraints constraints = new MediaConstraints();
                        constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
                        constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
                        // 或者使用可选约束（更兼容）
                        // constraints.optional.add(new MediaConstraints.KeyValuePair("googAudioSampleRate", "48000"));
                        // audioConstraints.optional.add(new MediaConstraints.KeyValuePair("googAudioSampleRate", 16000));
                        peerConnection.createAnswer(this, constraints);
                    } else {
                        Log.e(tag,"onSetSuccess2");
                        //是setLocalDescription回调
                        JSONObject sendObj = new JSONObject();
                        try {
                            sendObj.put("cmd", cmd_answer);
                            sendObj.put("uid", uid);
                            sendObj.put("remoteUid", remoteUid);
                            sendObj.put("roomId",roomId);
                            sendObj.put("msg", sdpDescription);
                            socket.send(sendObj.toString());

                        } catch (JSONException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

                @Override
                public void onCreateFailure(String s) {

                }

                @Override
                public void onSetFailure(String s) {

                }
            }, sdp);

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    private void handleNewPeer(JSONObject msgObj) {
        /*新人加入房间,创建offer,发起通话*/
        try {
            createWebrtc();

            //被呼叫者的uid
            remoteUid = msgObj.getString("uid");
            MediaConstraints constraints = new MediaConstraints();
            constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
            constraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
            peerConnection.createOffer(new SdpObserver() {
                private SessionDescription localSdp;

                @Override
                public void onCreateSuccess(SessionDescription sessionDescription) {
                    //创建offer成功即成功
                    localSdp = sessionDescription;
                    peerConnection.setLocalDescription(this, sessionDescription);
                }

                @Override
                public void onSetSuccess() {
                    //setLocalDescription 成功后回调
                    JSONObject sendObj = new JSONObject();
                    try {
                        sendObj.put("cmd", cmd_offer);
                        sendObj.put("uid", uid);
                        sendObj.put("remoteUid", remoteUid);
                        sendObj.put("roomId",roomId);
                        sendObj.put("msg", localSdp.description);
                        socket.send(sendObj.toString());
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public void onCreateFailure(String s) {

                }

                @Override
                public void onSetFailure(String s) {

                }
            }, constraints);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void onDestroy() {
        // 移除所有未执行的重连任务
        if (reconnectHandler != null) {
            reconnectHandler.removeCallbacksAndMessages(null);
        }
        closeSocket();

        if(peerConnection != null){
            peerConnection.close();
            peerConnection = null;
        }

        if(videoSource != null){
            videoSource.dispose();
            videoSource = null;
        }
        if (audioSource != null) {
            audioSource.dispose();
            audioSource = null;
        }
        if(videoCapturer != null){
            try {
                videoCapturer.stopCapture();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            videoCapturer.dispose();
            videoCapturer = null;
        }

        if(surfaceTextureHelper != null){
            surfaceTextureHelper.dispose();
            surfaceTextureHelper = null;
        }

        localRender.release();
        remoteRender.release();
        if(factory != null){
            factory.dispose();
            factory = null;
        }
        if(mRootEGL != null){
            mRootEGL.release();
            mRootEGL = null;
        }
        iceServers.clear();

        if (audioManager != null) {
            audioManager.setMode(AudioManager.MODE_NORMAL);
            audioManager.setSpeakerphoneOn(false);
            // 注意：不要设置为null，因为这是系统服务
            // audioManager = null;
        }
        // 设置屏幕常亮
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        super.onDestroy();
    }

    /**
     * 尝试重新连接WebSocket
     */
    private void attemptReconnect() {
        if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(WebrtcActivity.this, "重连失败，请检查网络后手动重试", Toast.LENGTH_LONG).show();
                }
            });
            return;
        }
        reconnectAttempts++;
        
        Log.e(tag, "尝试第" + reconnectAttempts + "次重连...");
        
        // 使用指数退避算法增加重连间隔
        long delay = RECONNECT_INTERVAL_MS * (long) Math.pow(2, reconnectAttempts - 1);
        reconnectHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                reconnectWebSocket();
            }
        }, delay);
    }
    
    /**
     * 重新建立WebSocket连接
     */
    private void reconnectWebSocket() {
        if (isDestroyed()) {
            return;
        }
        
        try {
            // 先释放旧的连接
            if (socket != null) {
                socket.close();
                socket = null;
            }
            
            // 重新创建连接
            createSocket();
        } catch (Exception e) {
            Log.e(tag, "重连失败: " + e.getMessage());
            // 如果重连失败，继续尝试
            attemptReconnect();
        }
    }
    

    private void doHangUp() {
        Log.e(tag, "主动挂断通话 doHangUp" );
        try {
            destroyWebrtc();
            if (audioManager != null) {
                audioManager.setMode(AudioManager.MODE_NORMAL);
                audioManager.setSpeakerphoneOn(false);
            }
            runOnUiThread(() -> {
                if (!isDestroyed() && !isFinishing()) {
                    changeState(TaskStatus.INIT);
                }
            });

        }catch (Exception e) {
            Log.e(tag, "doHangUp执行异常: " + e.getMessage());
            // 即使出现异常也要确保UI状态正确
            runOnUiThread(() -> {
                if (!isDestroyed() && !isFinishing()) {
                    changeState(TaskStatus.INIT);
                }
            });
        }
    }
}